home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Communications / Converse / Source / IconAnimator.m < prev    next >
Text File  |  1995-12-19  |  5KB  |  196 lines

  1. //** Craig Laurent
  2. #import "IconAnimator.h"
  3.  
  4. @implementation IconAnimator
  5.  
  6. /*  This is the callback function for the DPS Timed Entry. 
  7. It in turn calls our animateIcon method.  DPS Timed Entries require functions not methods, as callbacks. */
  8. void Animate (DPSTimedEntry timedEntry, double  now, void *who)
  9. {
  10.     [(id)who animateIcon];
  11. }
  12.  
  13.  
  14. - init
  15. {
  16.     return [self initWithImageArray:[NSMutableArray array] animationPattern:[NSMutableArray array] andPatternLoops:0];
  17. }
  18.  
  19. //** designated initializer
  20. - initWithImageArray:(NSArray*)anArray animationPattern:(NSArray*)patternArray andPatternLoops:(int)loops
  21. {
  22.     if (self = [super init]) {
  23.         //** set default value for instance variables
  24.         appTile = nil;
  25.         appIconContentView = nil;
  26.         imageArray = nil;
  27.         animationPattern = nil;
  28.         patternLoops = 0;
  29.         timeInterval = 0.2;
  30.         indexOfStopIcon = 0;
  31.         indexOfEndIcon = 1;
  32.         timedEntry = 0;
  33.         patternIterator = 0;
  34.         loopCount = 0;
  35.         patternEnd = 0;
  36.         offset = 0;
  37.  
  38.         //** set value for instance variables
  39.         appTile = [NXImage findImageNamed:"NXAppTile"];
  40.         appIconContentView = [[NXApp appIcon] contentView];
  41.         [self setImageArray:anArray];
  42.         [self setAnimationPattern:patternArray];
  43.         [self setPatternLoops:loops];
  44.         
  45.         return self;
  46.     }
  47.     return nil;
  48. }
  49.  
  50.  
  51. - (void)dealloc
  52. {
  53.     [imageArray autorelease];
  54.     [animationPattern autorelease];
  55.     [super dealloc];
  56. }
  57.  
  58.  
  59. //** instance methods
  60. - (NSArray*)imageArray
  61. { return imageArray; }
  62. - (void)setImageArray:(NSArray*)anArray
  63. {
  64.     [imageArray autorelease];
  65.     imageArray = [anArray retain];
  66. }
  67.  
  68. - (NSArray*)animationPattern
  69. { return animationPattern; }
  70. - (void)setAnimationPattern:(NSArray*)anArray
  71. {
  72.     [animationPattern autorelease];
  73.     animationPattern = [anArray retain];
  74.  
  75.     patternEnd = [animationPattern count];
  76. }
  77.  
  78. - (int)patternLoops
  79. {    return patternLoops; }
  80. - (void)setPatternLoops:(int)numLoops
  81. {    patternLoops = numLoops; }
  82.  
  83. - (float)timeInterval
  84. {    return timeInterval; }
  85. - (void)setTimeInterval:(float)interval
  86. {    timeInterval = interval; }
  87.  
  88. - (int)indexOfEndIcon
  89. {    return indexOfEndIcon; }
  90. - (void)setIndexOfEndIcon:(int)endIcon
  91. {    indexOfEndIcon = endIcon; }
  92.  
  93. - (int)indexOfStopIcon
  94. {    return indexOfStopIcon; }
  95. - (void)setIndexOfStopIcon:(int)stopIcon
  96. {    indexOfEndIcon = stopIcon; }
  97.  
  98.  
  99. //** methods to change Animation
  100. /* startAnimation - starts running the animation sequence */
  101. - (void)startAnimation:sender
  102. {
  103. //  if none exists, add a timed entry to begin the animation sequence...
  104.     
  105.     if (!timedEntry) {
  106.         timedEntry = DPSAddTimedEntry([self timeInterval], Animate, (void*)self, NX_MODALRESPTHRESHOLD);
  107.     }
  108. }
  109.  
  110. /* stopAnimation - stops the animation sequence and sets the application icon to a standard image */
  111. - (void)stopAnimation
  112. {
  113. //  Indicate Animation stopped by setting image to image one.  Do necessary housekeeping.
  114.     
  115.     [self removeTimedEntry];
  116.     if ([[self imageArray] count]) {
  117.         [self displayImage: (NXImage*)[[self imageArray] objectAtIndex: [self indexOfStopIcon]]];
  118.     }
  119.     patternIterator = 0;
  120.     loopCount = 0;
  121. }
  122.  
  123.  
  124. //** Internal methods
  125. /* removeTimedEntry - removes the timedEntry if it is running */
  126. - (void)removeTimedEntry
  127. {
  128.     if (timedEntry) {
  129.         DPSRemoveTimedEntry(timedEntry);
  130.         timedEntry = 0;
  131.     }
  132. }
  133.  
  134. /* cornerPointForImage: -  calculates and returns the point that should be used as the corner for this image.  This is used to make sure the image is centered on the application icon. */
  135. - (NXPoint)cornerPointForImage:(NXImage*)anImage
  136. {
  137. //*  You must center the composited image within
  138. //*   the contentView of the appIcon window.
  139.     NXSize    appTileSize;
  140.     NXSize    imageSize;
  141.     NXPoint    cornerPoint = { 0.0, 0.0 };
  142.  
  143.     [appTile getSize: &appTileSize];
  144.     [anImage getSize: &imageSize];
  145.     
  146.     if ( imageSize.width < appTileSize.width ) 
  147.         cornerPoint.x = (appTileSize.width - imageSize.width ) / 2.0;
  148.     
  149.     if ( imageSize.height < appTileSize.height ) 
  150.         cornerPoint.y = (appTileSize.height - imageSize.height ) / 2.0;
  151.         
  152.     return cornerPoint;
  153. }
  154.  
  155. /* displayImage: - displays the given image into the application icon. */
  156. - (void)displayImage:(NXImage*)anImage
  157. {
  158. //*  NXAppTile is composited first at 0,0 of the icon window's content view 
  159. //*  (this is required in order to maintain the NeXT icon look).
  160. //*  'anImage' is then composited at center (centering is also a requirement).
  161.  
  162.     NXPoint    contentViewOrigin = { 0.0, 0.0 };
  163.     NXPoint    cornerPoint = [self cornerPointForImage:anImage];
  164.     
  165.     [appIconContentView lockFocus];
  166.     [appTile composite:NX_SOVER toPoint:&contentViewOrigin];
  167.     [anImage composite:NX_SOVER toPoint:&cornerPoint];
  168.     [appIconContentView unlockFocus];
  169.     [appIconContentView display];
  170. }
  171.  
  172. /* animateIcon - called every time a timedEntry executes.  This contains logic for the icon animation (image sequencing).  The images contained in imageArray are used.  The animationPattern provides an index into that list, giving us the right image at the right time. */
  173. - (void)animateIcon
  174. {
  175.     [self displayImage: (NXImage*)[[self imageArray] objectAtIndex:[[[self animationPattern] objectAtIndex:patternIterator++] intValue]]];
  176.  
  177.     if (patternIterator == (patternEnd - offset)) {
  178.         [self removeTimedEntry];
  179.         patternIterator = 0;
  180.         loopCount++;
  181.         if (loopCount < [self patternLoops]) {
  182.             offset = 1;
  183. //** the following only works for Object, not NSObject
  184. //            [self perform: @selector(startAnimation:) with:nil afterDelay:500 cancelPrevious:YES];
  185.             [self perform: @selector(startAnimation:) withObject:nil];
  186.         } else {
  187.             loopCount = offset = 0;
  188.             [self displayImage:(NXImage*)[imageArray objectAtIndex: [self indexOfEndIcon]]];
  189.         }            
  190.     }
  191. }
  192.  
  193.  
  194.  
  195. @end
  196.